package puffer.starter.annotation.web.resource;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 资源注解处理器
 */
@Configuration
public class ResAnnotationHandler implements ApplicationContextAware {
    private static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ResAnnotationHandler.context = applicationContext;
    }

    public static synchronized HashMap<String, ArrayList<HashMap<String, Object>>> scanRes() {
        ArrayList<HashMap<String, Object>> cList = new ArrayList<>();
        ArrayList<HashMap<String, Object>> mList = new ArrayList<>();

        for (Object bean : ResAnnotationHandler.context.getBeansWithAnnotation(ResC.class).values()) {
            Class<?> aClass = bean.getClass();
            ResC resC = AnnotationUtils.findAnnotation(aClass, ResC.class);
            RestController restController = AnnotationUtils.findAnnotation(aClass, RestController.class);
            RequestMapping controllerMapping = AnnotationUtils.findAnnotation(aClass, RequestMapping.class);
            if (resC == null || restController == null || controllerMapping == null) continue;
            //遍历所有资源
            for (String cUrl : controllerMapping.value()) {
                //class
                HashMap<String, Object> moduleEntity = new HashMap<>();
                moduleEntity.put("name", resC.value());
                moduleEntity.put("parentName", resC.parent());
                if (resC.parent().equals("")) {
                    moduleEntity.put("parentName", resC.value());
                }
                moduleEntity.put("url", cUrl);
                cList.add(moduleEntity);

                //method
                Method[] declaredMethods = aClass.getDeclaredMethods();
                for (Method method : declaredMethods) {
                    RequestMapping requestMapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
                    ResM resMethod = AnnotationUtils.findAnnotation(method, ResM.class);
                    if (requestMapping == null || resMethod == null) continue;

                    //遍历所有资源
                    for (String methodValue : requestMapping.value()) {
                        String methodPath = cUrl + methodValue;
                        HashMap<String, Object> resEntity = new HashMap<>();
                        resEntity.put("url", methodPath);
                        resEntity.put("name", resMethod.value());
                        resEntity.put("parentName", resC.value());
                        resEntity.put("parentUrl", cUrl);
                        mList.add(resEntity);
                    }
                }
            }
        }

        HashMap<String, ArrayList<HashMap<String, Object>>> scanRes = new HashMap<>();
        scanRes.put("cList", cList);
        scanRes.put("mList", mList);
        return scanRes;
    }


}
